import React, {
  Component,
  createRef,
  createContext,
  useRef,
  useState,
  useEffect,
} from "react";
import PropType from "prop-types";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import gsap from "gsap"; //动画库
import Stats from "stats.js"; //性能监控
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js"; // FBX 模型加载器
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; //模型加载器
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader"; //模型解压缩

import "./Home.css";
import TagHook from "./components/tagHook";

import { loadShaderFromFile } from "./utlis";

import { CSS2DObject } from "three/examples/jsm/renderers/CSS2DRenderer.js"; //// 引入CSS2模型对象CSS2DObject
import { CSS2DRenderer } from "three/examples/jsm/renderers/CSS2DRenderer.js"; // 引入CSS2渲染器CSS2DRenderer

import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer"; //EffectComposer 效果组合器 它是处理 WebGLRenderer 效果的 接收 renderer为参数
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass"; // RenderPass 处理通道 它是处理 scene 场景和相机 camera 的。 接收 scene camera 为参数
import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass"; //UnrealBloomPass 泛光通道
import { FXAAShader } from "three/examples/jsm/shaders/FXAAShader.js"; //添加抗锯齿的效果
import { OutlinePass } from "three/examples/jsm/postprocessing/OutlinePass"; // 高亮发光描边通道 OutlinePass(画布宽高二维向量，场景scene,相机camera)

import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass.js"; // SMAA抗锯齿通道

import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass";
import { GammaCorrectionShader } from "three/examples/jsm/shaders/GammaCorrectionShader.js"; // 伽马校正后处理Shader

import WebGL from "three/examples/jsm//capabilities/WebGL.js";
import { ImprovedNoise } from "three/examples/jsm/math/ImprovedNoise"; //柏林噪声
// @ts-ignore
import { GUI } from "three/examples/jsm/libs/lil-gui.module.min";
import { Side } from "three";

let vertex: any, fragment: any;

const asyncF = async () => {
  // 初始化主色器程序
  vertex = await loadShaderFromFile("./shader/raw1/circular.fs.glsl");
  fragment = await loadShaderFromFile("./shader/raw1/circular.vt.glsl");
};
asyncF();
// var vertex = require('./shader/circular.fs.glsl');

// var fragment = require('./shader/circular.vt.glsl');

// import vertex from './shader/circular.fs.glsl';

// import fragment from './shader/circular.vt.glsl';

// import {vertex,fragment} from './shader/basic/demo'

if (WebGL.isWebGL2Available() === false) {
  document.body.appendChild(WebGL.getWebGL2ErrorMessage());
}

const width = window.innerWidth; //屏幕宽度
const height = window.innerHeight; //屏幕高度

// 渲染器
const renderer = new THREE.WebGLRenderer({
  antialias: true, //开启优化锯齿
});
renderer.setPixelRatio(window.devicePixelRatio); // 设置设备像素比。通常用于避免HiDPI设备上绘图模糊
renderer.setSize(width, height); // 将输出canvas的大小调整为(width, height)并考虑设备像素比，
// renderer.outputEncoding = THREE.sRGBEncoding; //定义渲染器的输出编码
// 相机
const camera = new THREE.PerspectiveCamera(
  60,
  window.innerWidth / window.innerHeight,
  0.1,
  100
);
camera.position.set(0, 0, 1.5);
// 场景
const scene = new THREE.Scene();

// 轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// controls.target.set(0, 12, 0);

// 性能监测 (这个不是three必须项)
const stats = new Stats(); // 性能监测

const ReactDemo = () => {
  let rawshaderMaterial: any;
  // 定义高斯函数

  const container = document.createElement("div");
  document.body.appendChild(container);

  const axesHelper = new THREE.AxesHelper(90); // 辅助线
  scene.add(axesHelper);

  // 纹理加载
  const textuerLoader = new THREE.TextureLoader()
  const texture = textuerLoader.load('./头像.jpg')



  // 创建原始着色器材质 原始着色器材质(RawShaderMaterial)
  rawshaderMaterial = new THREE.RawShaderMaterial({
    // 顶点着色器  （获取位置的点） void 表示没有返回值 main 入口函数 ，gl_Position 自带属性。可以获取到材质的 顶点数据（position） 注意结尾分好不能少
    //projectionMatrix * viewMatrix * modelMatrix * vec4(position,1.0);
    // 投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点矩阵（顶点着色器，一直遵循改法则）
    vertexShader: `
  
    // highp -2^16 - 2^16
    // mediump -2^10 - 2^10
    // lowp -2^8 - 2^8
    
    precision lowp float; // 数据精度（highp高 、 mediump 中  lowp 低） 声明 （必须写在这个位置）
    
    
    // attribute 声明变量  vec3 三维向量 position 顶点坐标
    // attribute 声明变量  vec2 2维向量 uv 顶点坐标
    attribute vec3 position;
    attribute vec2 uv;
    // uniform 声明变量  mat4 4×4浮点矩阵
    uniform mat4 modelMatrix;  // 模型矩阵
    uniform mat4 viewMatrix;  //视图矩阵
    uniform mat4 projectionMatrix;  // 投影矩阵
    uniform float uTime;
    // varying vec2 vUv 传递数据给片元着色器 把vUv 传递过去
    varying vec2 vUv;
    


    varying float vElevation;
    void main(){
        vUv = uv ; //赋值
        vec4 modelPosition = modelMatrix * vec4( position, 1.0 ) ; // 定义变量
        // modelPosition.x += 1.0 ; // x 轴移动 （注意数据是浮点数）
        // modelPosition.z += 1.0 ; // x 轴移动 （注意数据是浮点数）


        modelPosition.z = sin( (modelPosition.x+uTime) * 10.0) * 0.05; // 按照顶点位置变形
         modelPosition.z += sin( (modelPosition.y+uTime) * 10.0) * 0.05; // 按照顶点位置变形

        vElevation =  modelPosition.z; // 获取 高度，准备传递过去
        gl_Position = projectionMatrix * viewMatrix * modelPosition ;
    }

`,

    //碎片着色器 （渲染颜色） void 表示没有返回值 main 入口函数,gl_FragColor 自带属性， vec4 四维向量 注意结尾分好不能少
    fragmentShader: `
    

    // highp -2^16 - 2^16
    // mediump -2^10 - 2^10
    // lowp -2^8 - 2^8
    precision lowp float; // 数据精度（highp高 、 mediump 中  lowp 低） 声明 （必须写在这个位置）
    // varying vec2 vUv 接收顶点着色器传递过来的数据
    varying vec2 vUv;
    
    varying float vElevation;  // 接收传递过来的数
    
    //sampler2D: a handle for accessing a 2D texture 用于访问2D纹理的句柄
    uniform sampler2D uTexture; // 接收传递过来的 纹理 （sampler2D 采样）
    void main(){
    
      
    
       float height =vElevation + 0.05 * 10.0; // 因为传递过来的 数据 不能重新覆盖， 所以定义一直新的值 接收一下
        // gl_FragColor = vec4(1.0 * height,0.0,0.0,1.0);
    
        //  根据UV，取出对应的颜色
        //texture2D: 使用纹理坐标坐标进行当前2D纹理中的纹理查找绑定到采样器。
        vec4 textureColor = texture2D(uTexture,vUv);
        textureColor.rgb *=height;
        gl_FragColor = textureColor;
    }

`,
    wireframe: false, // 设置线框
    side: THREE.DoubleSide, // 双面渲染
    uniforms: {
      //传递数据给 着色器
      uTime: {
        value: 0,
      },
      // 把纹理数据传递和 着色器
      uTexture:{
        value:texture
      }
    },
  });
  //平面
  const floor = new THREE.Mesh(
    new THREE.PlaneGeometry(1, 1, 64, 64),
    rawshaderMaterial
  );

  scene.add(floor);

  // 性能监测
  container.appendChild(stats.dom);

  container.appendChild(renderer.domElement);

  window.addEventListener("resize", onWindowResize);
  renderer.domElement.addEventListener("click", handleModelClick);

  function onWindowResize() {
    camera.aspect = width / height;
    camera.updateProjectionMatrix();

    renderer.setSize(width, height);
  }

  function handleModelClick(event: MouseEvent) {
    const raycaster = new THREE.Raycaster();
    const pointer = new THREE.Vector2();
    pointer.x = (event.clientX / width) * 2 - 1;
    pointer.y = -(event.clientY / height) * 2 + 1;
    // 通过摄像机和鼠标位置更新射线
    raycaster.setFromCamera(pointer, camera);

    // 计算物体和射线的焦点
    const intersects: any = raycaster.intersectObjects(scene.children);

    console.log(intersects);
  }

  //
  const timeClock = new THREE.Clock(); // 获取时间
  function animate() {
    requestAnimationFrame(animate);

    const time = timeClock.getElapsedTime();
    //  if(rawshaderMaterial &&  rawshaderMaterial.uniforms){

    //  }
    rawshaderMaterial.uniforms.uTime.value = time;

    renderer.render(scene, camera);
    controls.update();

    stats.update();
  }

  animate();

  return <div></div>;
};

export default ReactDemo;
